
#include <queue>
#include <string>
#include <iostream>
#include <random>

using namespace std;

// get random
static inline int Random_int(int min, int max)
{
    std::random_device rd;
    std::mt19937_64 engine(rd());
    std::uniform_int_distribution dis1(min, max);
    return dis1(engine);
}

class Employee
{
    friend std::ostream &operator<<(std::ostream &, const Employee &);

public:
    Employee(const std::string &name, int age, int gender, int priority)
    {
        this->name = name;
        this->age = age;
        this->gender = gender;
        this->priority = priority;
    }

    // for sort
    bool operator<(const Employee &other) const
    {
        return priority < other.priority;
    }

protected:
private:
    std::string name;
    int age{-1};
    int gender{-1};   // 0,1
    int priority{-1}; // [0,9]
};
std::ostream &operator<<(std::ostream &os, const Employee &other)
{
    os << "{Name:" << other.name << ',';
    os << "Age:" << other.age << ',';
    os << "Gender:" << other.gender << ',';
    os << "Priority:" << other.priority << '}';
    return os;
}

void simpleTest();
void customTest();

int main(int argc, char const *argv[])
{
    customTest();
    return 0;
}

void customTest()
{
    bool printInfo = false;
    std::priority_queue<Employee> queue;
    for (int i = 0; i < 15; ++i)
    {
        if (printInfo)
        {
            Employee ee(std::to_string(i), Random_int(21, 65), Random_int(0, 1), Random_int(0, 9));
            queue.push(ee);
            cout << "add employee:" << ee << endl;
        }
        else
        {
            queue.emplace(std::to_string(i), Random_int(21, 65), Random_int(0, 1), Random_int(0, 9));
        }
    }
    cout << "current employee size: " << queue.size()
         << "\ncurrent top priority employee:"
         << queue.top() << endl;
}

void simpleTest()
{
    std::priority_queue<int, std::vector<int>, std::greater_equal<int>> queue;
    for (int i = 0; i < 100; ++i)
    {
        auto value = Random_int(10, 1000);
        queue.push(value);
        cout << "Add value:" << value << endl;
    }
    cout << "queue top:" << queue.top() << endl;
}